{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "from __future__ import print_function\n",
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from tensorflow.keras.datasets import mnist\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Dense, Activation\n",
    "from tensorflow.keras.optimizers import SGD\n",
    "from tensorflow.keras import utils  # np_utils.to_categrical"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义神经网络\n",
    "NB_EPOCH = 20\n",
    "BATCH_SIZE = 128\n",
    "VERBOSE = 1\n",
    "NB_CLASSES = 10\n",
    "OPTIMIZER = SGD()\n",
    "N_HIDDEN = 128\n",
    "VALIDATION_SPLIT = 0.2\n",
    "\n",
    "# 加入隐层\n",
    "N_HIDDEN = 128\n",
    "\n",
    "# 加入dropout\n",
    "DROPOUT = 0.5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ../train-images-idx3-ubyte.gz\n",
      "Extracting ../train-labels-idx1-ubyte.gz\n",
      "Extracting ../t10k-images-idx3-ubyte.gz\n",
      "Extracting ../t10k-labels-idx1-ubyte.gz\n"
     ]
    }
   ],
   "source": [
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "mnist = input_data.read_data_sets(\"../\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "# (X_trian, y_train), (X_test, y_test) = mnist\n",
    "X_train = mnist.train.images\n",
    "y_train = mnist.train.labels\n",
    "X_test = mnist.validation.images\n",
    "y_test = mnist.validation.labels\n",
    "\n",
    "# 字集28*28长度，784长度，训练集6W，测试集1W\n",
    "RESHAPED = 784\n",
    "\n",
    "# X_train = X_train.reshpe(55000, RESHAPED)\n",
    "# X_test = X_test.reshpe(10000, RESHAPED)\n",
    "X_train = X_train.astype('float32')\n",
    "X_test = X_test.astype('float32')  # float方便GPU计算等"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 归一化\n",
    "X_train /= 255\n",
    "X_test /= 255\n",
    "\n",
    "# 将向量归回分类问题\n",
    "\n",
    "Y_train = utils.to_categorical(y_train, NB_CLASSES)\n",
    "Y_test = utils.to_categorical(y_test, NB_CLASSES)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<bound method Network.summary of <tensorflow.python.keras.engine.sequential.Sequential object at 0x144a87128>>"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 单层网络\n",
    "# model = Sequential()\n",
    "# model.add(Dense(NB_CLASSES, input_shape=(RESHAPED,)))\n",
    "# model.add(Activation('softmax'))\n",
    "# model.summary\n",
    "\n",
    "# 增加隐层\n",
    "# model = Sequential()\n",
    "# model.add(Dense(N_HIDDEN, input_shape=(RESHAPED,)))\n",
    "# model.add(Activation('relu'))\n",
    "# model.add(Dense(N_HIDDEN))\n",
    "# model.add(Activation('relu'))\n",
    "# model.add(Dense(NB_CLASSES))\n",
    "# model.add(Activation('softmax'))\n",
    "# model.summary\n",
    "\n",
    "# 增加隐层和dropout\n",
    "model = Sequential()\n",
    "model.add(Dense(N_HIDDEN, input_shape=(RESHAPED,)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Dense(DROPOUT))\n",
    "model.add(Dense(N_HIDDEN))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Dense(DROPOUT))\n",
    "model.add(Dense(NB_CLASSES))\n",
    "model.add(Activation('softmax'))\n",
    "model.summary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 模型编译\n",
    "model.compile(loss='categorical_crossentropy', optimizer=OPTIMIZER, metrics=['accuracy'], )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 44000 samples, validate on 11000 samples\n"
     ]
    },
    {
     "ename": "AttributeError",
     "evalue": "'Tensor' object has no attribute 'assign'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-78-024bb14eb2db>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      1\u001b[0m history = model.fit(X_train, Y_train, batch_size=BATCH_SIZE, epochs=NB_EPOCH, \n\u001b[0;32m----> 2\u001b[0;31m                     verbose=VERBOSE, validation_split=VALIDATION_SPLIT)\n\u001b[0m",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, max_queue_size, workers, use_multiprocessing, **kwargs)\u001b[0m\n\u001b[1;32m    878\u001b[0m           \u001b[0minitial_epoch\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0minitial_epoch\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    879\u001b[0m           \u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 880\u001b[0;31m           validation_steps=validation_steps)\n\u001b[0m\u001b[1;32m    881\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    882\u001b[0m   def evaluate(self,\n",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_arrays.py\u001b[0m in \u001b[0;36mmodel_iteration\u001b[0;34m(model, inputs, targets, sample_weights, batch_size, epochs, verbose, callbacks, val_inputs, val_targets, val_sample_weights, shuffle, initial_epoch, steps_per_epoch, validation_steps, mode, validation_in_fit, **kwargs)\u001b[0m\n\u001b[1;32m    193\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    194\u001b[0m   \u001b[0;31m# Get step function and loop type.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 195\u001b[0;31m   \u001b[0mf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_make_execution_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmode\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    196\u001b[0m   \u001b[0muse_steps\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msteps_per_epoch\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    197\u001b[0m   \u001b[0mdo_validation\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mval_inputs\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_arrays.py\u001b[0m in \u001b[0;36m_make_execution_function\u001b[0;34m(model, mode)\u001b[0m\n\u001b[1;32m    120\u001b[0m   \u001b[0;32mif\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_distribution_strategy\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    121\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0mtraining_distributed\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_make_execution_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmode\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 122\u001b[0;31m   \u001b[0;32mreturn\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_make_execution_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmode\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    123\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    124\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py\u001b[0m in \u001b[0;36m_make_execution_function\u001b[0;34m(self, mode)\u001b[0m\n\u001b[1;32m   1981\u001b[0m   \u001b[0;32mdef\u001b[0m \u001b[0m_make_execution_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmode\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1982\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0mmode\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'train'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1983\u001b[0;31m       \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_make_fit_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1984\u001b[0m       \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_fit_function\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1985\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0mmode\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'test'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py\u001b[0m in \u001b[0;36m_make_fit_function\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1924\u001b[0m     ]\n\u001b[1;32m   1925\u001b[0m     self._make_train_function_helper(\n\u001b[0;32m-> 1926\u001b[0;31m         '_fit_function', [self.total_loss] + metrics_tensors)\n\u001b[0m\u001b[1;32m   1927\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1928\u001b[0m   \u001b[0;32mdef\u001b[0m \u001b[0m_make_test_function_helper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfn_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moutputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmetric_updates\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py\u001b[0m in \u001b[0;36m_make_train_function_helper\u001b[0;34m(self, fn_name, outputs, metric_updates)\u001b[0m\n\u001b[1;32m   1893\u001b[0m             \u001b[0;31m# Training updates\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1894\u001b[0m             updates = self.optimizer.get_updates(\n\u001b[0;32m-> 1895\u001b[0;31m                 params=self._collected_trainable_weights, loss=self.total_loss)\n\u001b[0m\u001b[1;32m   1896\u001b[0m       \u001b[0;31m# Unconditional updates\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1897\u001b[0m       \u001b[0mupdates\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_updates_for\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/keras/optimizers.py\u001b[0m in \u001b[0;36mget_updates\u001b[0;34m(self, loss, params)\u001b[0m\n\u001b[1;32m    200\u001b[0m     \u001b[0;32mfor\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mm\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparams\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgrads\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmoments\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    201\u001b[0m       \u001b[0mv\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmomentum\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mm\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mlr\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mg\u001b[0m  \u001b[0;31m# velocity\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 202\u001b[0;31m       \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdates\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate_ops\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0massign\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mm\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    203\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    204\u001b[0m       \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnesterov\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/ops/state_ops.py\u001b[0m in \u001b[0;36massign\u001b[0;34m(ref, value, validate_shape, use_locking, name)\u001b[0m\n\u001b[1;32m    222\u001b[0m         \u001b[0mref\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0muse_locking\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0muse_locking\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    223\u001b[0m         validate_shape=validate_shape)\n\u001b[0;32m--> 224\u001b[0;31m   \u001b[0;32mreturn\u001b[0m \u001b[0mref\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0massign\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    225\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    226\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'Tensor' object has no attribute 'assign'"
     ]
    }
   ],
   "source": [
    "history = model.fit(X_train, Y_train, batch_size=BATCH_SIZE, epochs=NB_EPOCH, \n",
    "                    verbose=VERBOSE, validation_split=VALIDATION_SPLIT)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5000/5000 [==============================] - 0s 25us/sample - loss: 0.3461 - acc: 0.9008\n",
      "Test Score: 0.34606637340784074\n",
      "Test Accuracy: 0.9008\n"
     ]
    }
   ],
   "source": [
    "score = model.evaluate(X_test, Y_test, verbose=VERBOSE)\n",
    "print(\"Test Score:\", score[0])\n",
    "print(\"Test Accuracy:\", score[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
